package com.loveprogrammer.eternity.factory;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.loveprogrammer.eternity.factory.template.EffectTemplate;
import com.loveprogrammer.eternity.factory.template.MapTemplate;
import com.loveprogrammer.eternity.model.effect.AbstractEffect;
import com.loveprogrammer.eternity.model.effect.SuckBloodEffect;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Constructor;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @version 1.0.0
 * @description:
 * @author: eric
 * @date: 2023-02-15 18:45
 **/
public class EffectFactory {

    private static Map<Integer, EffectTemplate> map;

    static {
        try {
            // 读取配置文件，然后加载到weaponTemplates中
            ClassLoader classLoader = EquipmentFactory.class.getClassLoader();
            InputStream inputStream = classLoader.getResourceAsStream("effect.json");

            assert inputStream != null;
            BufferedReader streamReader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
            StringBuilder responseStrBuilder = new StringBuilder();

            String inputStr;
            while ((inputStr = streamReader.readLine()) != null)
                responseStrBuilder.append(inputStr);

            List<EffectTemplate> list = JSONArray.parseArray(responseStrBuilder.toString(), EffectTemplate.class);

            map = list.stream().collect(Collectors.toMap(EffectTemplate::getId, e->e));

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static EffectTemplate getTemplateById(int id) {
        return map.get(id);
    }

    public static AbstractEffect getEffectById(int id) {

        EffectTemplate effectTemplate = map.get(id);
        String className = effectTemplate.getClassName();
        List<Object> params = effectTemplate.getParams();

        try {
            Class<?> clazz = Class.forName(className);
            Constructor<?>[] constructors = clazz.getConstructors();
            // 遍历所有的构造方法
            for (Constructor<?> constructor : constructors) {
                if(params != null && params.size() > 0
                        && constructor.getParameterTypes().length == params.size()+1){
                    Object[] args = new Object[params.size()+1];
                    args[0] = UUID.randomUUID().toString();
                    for (int i = 0; i < params.size(); i++) {
                        args[i+1] = params.get(i);
                    }
                    return (AbstractEffect) clazz.getDeclaredConstructor(constructor.getParameterTypes()).newInstance(args);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) throws IOException {
//        AbstractEffect effect = getEffectById(1);
//        assert effect != null;
//        System.out.println(effect.getId());


        // 读取配置文件，然后加载到weaponTemplates中
        ClassLoader classLoader = EquipmentFactory.class.getClassLoader();
        InputStream inputStream = classLoader.getResourceAsStream("effects.json");

        assert inputStream != null;
        BufferedReader streamReader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
        StringBuilder responseStrBuilder = new StringBuilder();

        String inputStr;
        while ((inputStr = streamReader.readLine()) != null)
            responseStrBuilder.append(inputStr);

        List<SuckBloodEffect> list = JSONArray.parseArray(responseStrBuilder.toString(), SuckBloodEffect.class);
        System.out.println(JSON.toJSON(list));
    }

    public static List<AbstractEffect> getRandomEffect(int num) {
        List<AbstractEffect> list = new ArrayList<>();
        if(num > map.size()) {
            num = map.size();
        }
        List<Integer> keys = new ArrayList<>(map.keySet());
        Collections.shuffle(keys);
        for (int i = 0; i < num; i++) {
            Integer key = keys.get(i);
            AbstractEffect effect = getEffectById(map.get(key).getId());
            list.add(effect);
        }
        return list;
    }

    public static List<EffectTemplate> getRandomEffectTemplate(int num) {
        List<EffectTemplate> list = new ArrayList<>();
        if(num > map.size()) {
            num = map.size();
        }
        List<Integer> keys = new ArrayList<>(map.keySet());
        Collections.shuffle(keys);
        for (int i = 0; i < num; i++) {
            Integer key = keys.get(i);
            EffectTemplate template = getTemplateById(key);
            list.add(template);
        }
        return list;
    }
}
